﻿///////////////////////////////////////////////////////////////////////////
// 文件名:     deviceoperator.cpp
// 描述:
// 作者:      颜磊
// 创建工程：   SpaceClear
// 创建时间:   2024-07-24 15:51
///////////////////////////////////////////////////////////////////////////
#include "deviceoperator.h"

#include <iostream>

DeviceOperator::DeviceOperator()
{
}

DeviceOperator::~DeviceOperator()
{
}

BOOL DeviceOperator::InstallServiceInterface(const char *Name, const wchar_t *Description, const char *Path)
{
    SC_HANDLE schSCManager; //SCM驱动管理句柄
    SC_HANDLE schService;   //驱动程序的服务句柄

    //打开服务控制管理器
    schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (schSCManager == NULL)
    {
        std::cout << "安装驱动失败！" << std::endl;
    }

    //创建驱动对应的服务
    schService = CreateServiceA(schSCManager,                                            // SCManager database
                                Name,                                                    // name of service    //驱动程序在注册表中的名字
                                Name,                                                    // name to display    //注册表驱动程序的DisplayName值
                                SERVICE_ALL_ACCESS,                                      // desired access  //加载驱动程序的访问权限
                                SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, // service type
                                SERVICE_AUTO_START,                                      // start type
                                SERVICE_ERROR_NORMAL,                                    // error control type
                                Path,                                                    // service's binary
                                NULL,                                                    // no load ordering group
                                NULL,                                                    // no tag identifier
                                NULL,                                                    // no dependencies
                                NULL,                                                    // LocalSystem account
                                NULL                                                     // no password
    );

    DWORD dwRtn;
    if (schService == NULL)
    {
        dwRtn = GetLastError();
        if (dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS)
        {
            std::cout << "服务创建失败" << std::endl;
        }
        else
        {
            std::cout << "服务已经创建过" << std::endl;
        }
    }

    SERVICE_DESCRIPTION sd;

    sd.lpDescription = (LPWSTR)Description;

    ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &sd);

    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);

    return NULL == schService ? FALSE : TRUE;
}

void DeviceOperator::UninstallServiceInterface(const char *Name)
{
    SC_HANDLE schSCManager;
    SC_HANDLE schService;
    BOOL ret = 0;
    SERVICE_STATUS serviceStatus;

    schSCManager = OpenSCManager(NULL,                 // machine (NULL == local)
                                 NULL,                 // database (NULL == default)
                                 SC_MANAGER_ALL_ACCESS // access required
    );

    schService = OpenServiceA(schSCManager, Name, SERVICE_ALL_ACCESS);
    if (schService == NULL)
    {
        CloseServiceHandle(schSCManager);
        return;
    }

    //先停止服务，再删除服务
    ret = ControlService(schService, SERVICE_CONTROL_STOP, &serviceStatus);

    ret = DeleteService(schService);

    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);
}

BOOL DeviceOperator::StartServiceInterface(const char *lpszServiceName)
{
    SC_HANDLE schSCManager;
    SC_HANDLE schService;
    BOOL ret = 0;
    SERVICE_STATUS serviceStatus;

    schSCManager = OpenSCManager(NULL,                 // machine (NULL == local)
                                 NULL,                 // database (NULL == default)
                                 SC_MANAGER_ALL_ACCESS // access required
    );

    schService = OpenServiceA(schSCManager, lpszServiceName, SERVICE_ALL_ACCESS);
    if (schService == NULL)
    {
        CloseServiceHandle(schService);
        CloseServiceHandle(schSCManager);
        return FALSE;
    }
    if (StartService(schService, NULL, NULL) == FALSE)
    {
        CloseServiceHandle(schService);
        CloseServiceHandle(schSCManager);
        return FALSE;
    }
    SERVICE_STATUS svcStatus;
    while (QueryServiceStatus(schService, &svcStatus))
    {
        if (svcStatus.dwCurrentState == SERVICE_RUNNING)
        {
            CloseServiceHandle(schService);
            CloseServiceHandle(schSCManager);
            return TRUE;
        }
    }
    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);
    return FALSE;
}

BOOL DeviceOperator::StopServiceInterface(const char *lpszServiceName)
{
    SC_HANDLE schSCManager;
    SC_HANDLE schService;
    SERVICE_STATUS serviceStatus;

    schSCManager = OpenSCManager(NULL,                 // machine (NULL == local)
                                 NULL,                 // database (NULL == default)
                                 SC_MANAGER_ALL_ACCESS // access required
    );

    schService = OpenServiceA(schSCManager, lpszServiceName, SERVICE_ALL_ACCESS);
    if (schService == NULL)
    {
        CloseServiceHandle(schSCManager);
        return FALSE;
    }

    if (ControlService(schService, SERVICE_CONTROL_STOP, &serviceStatus) == FALSE)
    {
        //        std::cout << "服务停止指令下发失败!" << std::endl;
        CloseServiceHandle(schService);
        CloseServiceHandle(schSCManager);
        return FALSE;
    }
    while (QueryServiceStatus(schService, &serviceStatus) == TRUE)
    {
        if (serviceStatus.dwCurrentState == SERVICE_STOPPED)
        {
            CloseServiceHandle(schService);
            CloseServiceHandle(schSCManager);
            return TRUE;
        }
    }
    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);
    return FALSE;
}

int DeviceOperator::getServiceState(const char *lpszServiceName)
{
    SC_HANDLE schSCManager;
    SC_HANDLE schService;
    SERVICE_STATUS serviceStatus;

    schSCManager = OpenSCManager(NULL,                 // machine (NULL == local)
                                 NULL,                 // database (NULL == default)
                                 SC_MANAGER_ALL_ACCESS // access required
    );
    if (schSCManager == NULL)
    {
        CloseServiceHandle(schSCManager);
        return -2;
    }

    schService = OpenServiceA(schSCManager, lpszServiceName, SERVICE_ALL_ACCESS);
    if (schService == NULL)
    {
        CloseServiceHandle(schService);
        CloseServiceHandle(schSCManager);
        return -1;
    }

    if (QueryServiceStatus(schService, &serviceStatus) == TRUE)
    {
        CloseServiceHandle(schService);
        CloseServiceHandle(schSCManager);
        return serviceStatus.dwCurrentState;
    }
    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);
    return -1;
}
